# Наблюдение за приложениями

Sidecar прокси-контейнеры Istio перехватывают весь траффик приложения, что позволяет им 
анализировать данные и атрибуты HTTP траффика без каких либо изменений в самом приложении. Таким образом "из коробки" мы получаем мониторинг, логирование, распределенную трассировку и схемы взаимодействия приложений.
 
Взглянем на Pod-ы и Service-ы, созданные в `istio-system` namespace и обратите внимание на сервисы `grafana`, `jaeger`, `kiali`, `prometheus`, `tracing`, `zipkin`:
```
kubectl get pods -n istio-system

kubectl get services -n istio-system
```
Чтобы продемонстрировать, функционал наблюдения за приложением, нам необходимо создать постоянную нагрузку на наши микросервисы. Давайте запустим процесс заказов кофе в цикле c периодичностью в 1 секунду:
```
while true; do
curl <ip-address>:<node-port>/coffee-shop/resources/orders -i -XPOST \
    -H 'Content-Type: application/json' \
    -d '{"type":"Espresso"}' \
    | grep HTTP
sleep 1
done
```


## Мониторинг (интерфейс Grafana)


Istio "из коробки" предоставляет мониторинг и Grafana—дашборды . Чтобы продемоснтрировать работу с мониторингом, нам нужно установить соединение с Pod-ом Grafana.

Мы могли бы создать выделенный service и gateway, который направит
траффик к Pod-у, но для тестовых целей мы сделаем быстрее тунелирование трафика
с локального порта `3000` на Grafana Pod в порт `3000`:
```
kubectl -n istio-system port-forward \
    $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') \
    3000:3000 &
```

> **Примечание**
>
> Важно иметь в виду, что в данном примере исползуется локальный порт `3000`, который может быть занят на вашей машине другим приложением. В таком случае укажите в команде тунелирования трафика другой свободный локальный порт отличный от `3000`.

Как только эта переадресация будет выполнена, откройте в браузере пользовательский интерфейс Grafana по ссылке <http://localhost:3000>, затем передийте к Istio Mesh Dashboard, щелкнув на Home в левом верхнем углу.

Далее вы сможете изучить технические метрики, которые доступны в Istio по умолчанию. 

## Схемы взаимодействий (интерфейс Kiali)

Istio также поставляется с функционалом по построению схем взаимодействия сервисов, который показывает зависимости и взаимодействия между отдельными сервисами.

Выполним тунелирование трафика из локального порта `20001` на порт Kiali Pod-а:
```
kubectl -n istio-system port-forward \
    $(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') \
    20001:20001 &
```
Откроем Kiali консоль по ссылке <http://localhost:20001/> логин-пароль `admin/admin` и исследуем варианты схем в разделе `Graph`. Изучите доступные опции параметров `Display` и `Graph Type`.

## Распределенная трассировка (интерфейс Jaeger)

Istio также поставляется с распределенной трассировкой, которая позволяет отследить отдельные запросы, которые произошли между нашими микросервисами.

Распределенная трассировка — единственная функция наблюдения, которая
не работает из коробки без действия с нашей стороны. По умолчанию
Istio  не может узнать, что два отдельных HTTP-запроса: один между 
ingress gateway и coffe-shop service, и второй между приложениями 
coffe-shop и barista, на самом деле взаимосвязаны.

Внутри должно произойти следующее: приложение coffe-shop должно извлечь
и передать определенные HTTP заголовки трассировки
(`x-b3-traceid`, `x-b3-parentspanid`, `x-b3-spanid`, …), а Sidecar-ы
затем смогут скоррелировать эту информацию для выстравивания сквозных трасс запросов между несколькими сервисами.

Это означает, что наше приложение coffe-shop должно взять заголовки трассировки из входящего HTTP-запроса, сохранить их в потоке обработки запроса и далее добавить их в исходящий HTTP-запрос к сервису barista. К счастью, с помощью MicroProfile OpenTracing, нам не нужно это делать вручную.

Наше приложение может быть настроено на использование MicroProfile OpenTracing, который передает эту информацию из входящих в исходящие HTTP-запросы, если заголовки трассировки были доступны при первом запросе.

Для этого нам нужно только дать указание нашим серверам OpenLiberty
активировать соответствующую функцию. Нам не нужно менять ни Java код, 
ни сборку приложения. Это настраивается исключительно на уровне инфраструктуры.

Взглянем на конфигурацию нашего coffe-shop приложения `liberty/server.xml`:
помимо `jakartaee-8.0`, она содержит `microProfile-3.0` и  `usr:opentracingZipkin-0.31`. Это позволит автоматически передавать HTTP-заголовки трассировки.

```xml
    ...

    <featureManager>
        <feature>jakartaee-8.0</feature>
        <feature>microProfile-3.0</feature>
        <feature>usr:opentracingZipkin-0.31</feature>
    </featureManager>

    ...
```

Теперь выполним тунелирование трафика с локального порта 16686 на порт Jaeger Pod-а:
```
kubectl port-forward -n istio-system \
    $(kubectl get pod -n istio-system -l app=jaeger -o jsonpath='{.items[0].metadata.name}') \
    16686:16686 &
```
Перейдем к консоли Jaeger по ссылке <http://localhost:16686>, выберем `istio-ingressgateway` как сервис, и кликнем на кнопку *`Find Traces`*, чтобы посмотреть последние трейсы.
 
Если вы посмотрите на несколько трейсов, то заметите, что наше coffe-shop
приложение вызывает barista в синхронном и ассинхронном режиме. Для синхронного взаимодействия в трейсе будет онда цепочка вызовов: `istio-ingressgateway->coffee-shop->barista`. А для ассинхронного в трейсе будет две цепочки: `istio-ingressgateway->coffee-shop` и `coffee-shop->barista`.

В [следующем разделе](06-istio-routing.md) мы рассмотрим как настроить Istio
для маршрутизации траффика в соответствии с определенными критериями.
